using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;


/* Author: Juan Carlos Recio Abad
 * E-mail: juan.carlos.recio.abad@gmail.com 
 * Project: Windows Phone XNA Games Scrolling Functionality
 */
namespace ScrollingFunctionality
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        const float MAX_POS_START_WORLD_MAP_Y = 1248;
        const int WIDTH = 480, HEIGHT = 800;

        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        // We need to check the top border nearly every moment:
        float TopBorder;

        // Reference to the last touching 
        TouchLocation LastTouch;

        // We also have to know when the screen is starting to move, moving and ending its movement
        // Screen is being scrolled
        bool dragging;

        // Gets the current position clicked over the screen to start properly the screen //movement
        bool onDrag;

        // Background: It’s supposed to be a background larger than the screen
        Rectangle backgroundRectangle; // Rectangle to locate/resize it
        Texture2D backgroundTexture; // Texture to be drawn over the screen just in a certain part

        Texture2D itemClickedItem; // Example item to implement clickable parts
        Texture2D itemUnclickedItem; // Example item to implement clickable parts

        // Simple dictionary to detect clicks
        KeyValuePair<Int32, Int32>[] clickableZones;

        KeyValuePair<Int32, Int32> exampleClickedItem;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            // Frame speed
            TargetElapsedTime = TimeSpan.FromTicks(333333);

            InactiveSleepTime = TimeSpan.FromSeconds(1);
        }

        protected override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            graphics.PreferredBackBufferWidth = WIDTH;
            graphics.PreferredBackBufferHeight = HEIGHT;
            graphics.IsFullScreen = true;
            graphics.SupportedOrientations = DisplayOrientation.Portrait;
            graphics.ApplyChanges();

            // Here we load the resources
            backgroundRectangle = new Rectangle(0, 0, WIDTH, HEIGHT);

            // Here we use an image called "background.png" located in the resources folder content of the project
            backgroundTexture = Content.Load<Texture2D>("background");

            // When a clickable part be clicked, we will draw an star on, and off when unclicked
            itemClickedItem = Content.Load<Texture2D>("staron");
            itemUnclickedItem = Content.Load<Texture2D>("staroff");

            dragging = false;

            // Here we decide the ABSOLUTE coordinates of the clickable parts
            // We take for granted a 100x100 clickable part and we set the center planets as clickable parts
            clickableZones = new KeyValuePair<int, int>[4];
            clickableZones[0] = new KeyValuePair<Int32,Int32>(170, 1850);
            clickableZones[1] = new KeyValuePair<Int32, Int32>(170, 1400);
            clickableZones[2] = new KeyValuePair<Int32, Int32>(170, 1100);
            clickableZones[3] = new KeyValuePair<Int32, Int32>(170, 800);
            // Not use a dictionary because of X couldn't be repeated


            exampleClickedItem = new KeyValuePair<int, int>(0, 0);
        }

        protected override void UnloadContent()
        {
          
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // Catching the position and status of the click
            var touch = TouchPanel.GetState().FirstOrDefault();
            
            bool pressed = touch.State == TouchLocationState.Pressed;
            bool released = touch.State == TouchLocationState.Released;

            if (released)
            {
                dragging = false;
            }
            else if (pressed)
            {
                onDrag = true;
                dragging = true;
            }

            if (onDrag)
            {
                LastTouch = touch;
                onDrag = false;
                exampleClickedItem = new KeyValuePair<int, int>(0, 0);
            }
            if (dragging)
            {
                float difference = (touch.Position.Y - LastTouch.Position.Y);
                TopBorder -= difference;
                if (TopBorder > MAX_POS_START_WORLD_MAP_Y) TopBorder = MAX_POS_START_WORLD_MAP_Y;
                else if (TopBorder < 0) TopBorder = 0;
                LastTouch = touch;
            }
            if (pressed)
            {
                int X = (int)touch.Position.X, Y = (int)touch.Position.Y;

                // Of course there are other better performances to make this detection, this is just a random one
                var clickableRectangles = clickableZones
                    .Select((i)=> new Rectangle(i.Key, i.Value, 100, 100));

                foreach (var rectangle in clickableRectangles)
                {
                    if (rectangle.Contains(X, Y + (int)TopBorder))
                    {
                        exampleClickedItem = new KeyValuePair<Int32, Int32>(X, Y + (int)TopBorder);
                        break;
                    }
                }
            }

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.White);

            spriteBatch.Begin();

            int startYscreen = (int)TopBorder;

            spriteBatch.Draw(backgroundTexture, new Rectangle(0, -startYscreen, 480, 2048), Color.White);

            foreach (var kvp in clickableZones)
            {
                if (new Rectangle(kvp.Key, kvp.Value, 100, 100).Contains(exampleClickedItem.Key, exampleClickedItem.Value))
                {
                    spriteBatch.Draw(itemClickedItem, new Vector2((float)kvp.Key, (float)kvp.Value - TopBorder), Color.White);
                }
                else
                {
                    spriteBatch.Draw(itemUnclickedItem, new Vector2((float)kvp.Key, (float)kvp.Value - TopBorder), Color.White);
                }
            }
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}
